package com.ctw.tinyservices.id.sdk.snowflake;

import com.ctw.tinyservices.id.common.enums.state.IdLifecycleState;
import com.ctw.tinyservices.id.common.exception.AuthException;
import com.ctw.tinyservices.id.core.IdGenerator;
import com.ctw.tinyservices.id.core.snowflake.generator.IdSnowflakeGenerator;
import com.ctw.tinyservices.id.sdk.AbstractIdSdk;
import com.ctw.tinyservices.id.common.exception.HttpException;
import com.ctw.tinyservices.id.sdk.enums.HttpMethodEnum;
import com.ctw.tinyservices.id.sdk.util.OkHttpUtils;
import com.ctw.tinyservices.id.sdk.util.ServerLoadBalanceUtils;
import com.google.common.base.Strings;

/**
 * @author TongWei.Chen 2022/3/21 20:53
 *
 * 雪花算法sdk
 **/
public class IdSnowflakeSdk extends AbstractIdSdk {

    private volatile boolean isAuth;
    private Object monitor = new Object();
    private IdGenerator idSnowflakeGenerator;

    /**
     * 单例
     */
    private IdSnowflakeSdk(String location) {
        this.location = location;
    }

    private volatile static IdSnowflakeSdk singleton;
    public static IdSnowflakeSdk getInstance(String location) {
        if (singleton == null) {
            synchronized (IdSnowflakeSdk.class) {
                if (singleton == null) {
                    singleton = new IdSnowflakeSdk(location);
                }
            }
        }
        return singleton;
    }

    @Override
    public Long getId(String bizType) {
        if (! isAuth) {
            synchronized (monitor) {
                if (! isAuth) {
                    StringBuilder url =
                            new StringBuilder(ServerLoadBalanceUtils.getUrl(HttpMethodEnum.SNOWFLAKE_AUTH))
                                    .append(HttpMethodEnum.getSnowflakeAuthParam(bizType));
                    String response = OkHttpUtils.get(url.toString(), null, ServerLoadBalanceUtils.getHeader());
                    if (Strings.isNullOrEmpty(response)) {
                        throw new HttpException(url.toString(), bizType);
                    }
                    if (! Boolean.parseBoolean(response)) {
                        throw new AuthException("auth fail");
                    }
                    isAuth = true;
                }
            }
        }
        return idSnowflakeGenerator.getId(bizType);
    }

    @Override
    protected void doInit() {
        super.doInit();

        long epoch = idConfigSupport.getEpoch();

        StringBuilder url =
                new StringBuilder(ServerLoadBalanceUtils.getUrl(HttpMethodEnum.GET_SNOWFLAKE_WORKERID));
        String response = OkHttpUtils.get(url.toString(), null, ServerLoadBalanceUtils.getHeader());
        if (Strings.isNullOrEmpty(response)) {
            throw new HttpException(url.toString(), "");
        }
        int workerId = Integer.parseInt(response);
        idSnowflakeGenerator = new IdSnowflakeGenerator(workerId, epoch);

        idSnowflakeGenerator.setState(IdLifecycleState.INIT);
        idSnowflakeGenerator.setState(IdLifecycleState.START);
    }

}
